/*
 * NewComponentDialog.java
 *
 * Created on March 12, 2005, 12:24 AM
 */

package gui;

import circuitsandbox.ImageFileFilter;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.HashSet;
import javax.swing.JDialog;
import javax.swing.JFileChooser;

/**
 * A dialog box for saving a custom component.
 *
 * @author Daniel Stahl
 * @author Kevin Wellwood
 */
public class NewComponentDialog extends JDialog {
    
    /** Creates new form NewComponentDialog
     *
     * @param gui the gui
     * @param inputs the collection of input components
     * @param outputs the collection of output components
     */
    public NewComponentDialog(Gui gui, HashSet inputs, HashSet outputs) {
        super(gui);
        this.inputs = inputs;
        this.outputs = outputs;
        
        initComponents();
        
        for (int i = 0; i < componentPane.getInputPins().size(); i++) {
            // set the component image's pin number so it can display itself
            PlaceholderPin pin = (PlaceholderPin)componentPane.getInputPins().get(i);
            pin.getLogicComponent().getComponentImage().setCustomComponentPin(i);
        }
        for (int i = 0; i < componentPane.getOutputPins().size(); i++) {
            // set the component image's pin number so it can display itself
            PlaceholderPin pin = (PlaceholderPin)componentPane.getOutputPins().get(i);
            pin.getLogicComponent().getComponentImage().setCustomComponentPin(i);
        }
        
        // zoom out the sandbox and refresh it so we can see the input and
        // output components with their numbers
        gui.setZoomFactor(0.5f);
    }
       
    /**
     * Displays the dialog for the user.
     *
     * @return the user's response, either <code>ACCEPT</code> or
     * <code>CANCEL</code>
     */
    public int showDialog() {
        setVisible(true);
        
        // clear the numbers from the input and output components' images
        ArrayList inputPins = componentPane.getInputPins();
        for (int i = 0; i < inputPins.size(); i++) {
            PlaceholderPin pin = (PlaceholderPin)inputPins.get(i);
            pin.getLogicComponent().getComponentImage().setCustomComponentPin(-1);
        }
        ArrayList outputPins = componentPane.getOutputPins();
        for (int i = 0; i < outputPins.size(); i++) {
            PlaceholderPin pin = (PlaceholderPin)outputPins.get(i);
            pin.getLogicComponent().getComponentImage().setCustomComponentPin(-1);            
        }
        return optionChosen;
    }
    
    /**
     * Returns the plain english name the user entered for the component.
     *
     * @return the name
     */
    public String getComponentName() {
        return nameField.getText();
    }
    
    /**
     * Returns the image the user selected to represent the component
     *
     * @return the image
     */
    public Image getImage() {
        return componentPane.getImage();
    }
    
    /**
     * Returns an array of the custom component's input pins.
     *
     * @return the array of input pins (instances of PlaceholderPin)
     *
     * @see PlaceholderPin
     */
    public ArrayList getInputPins() {
        return componentPane.getInputPins();
    }
    
    /**
     * Returns an array of the custom component's output pins.
     *
     * @return the array of output pins (instances of PlaceholderPin)
     *
     * @see PlaceholderPin
     */
    public ArrayList getOutputPins() {
        return componentPane.getOutputPins();
    }
    
    /**
     * Verifies that the form is complete. If it is, the save button is enabled,
     * otherwise it is disabled so that the user must finish completing the
     * dialog before saving.
     */
    private void verifyForm() {
        if (nameField.getText().trim().length() > 0)
            saveButton.setEnabled(true);
        else
            saveButton.setEnabled(false);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        javax.swing.JButton cancelButton;
        javax.swing.JPanel componentPanel;
        javax.swing.JPanel confirmPanel;
        java.awt.GridBagConstraints gridBagConstraints;
        javax.swing.JLabel imageLabel;
        javax.swing.JPanel imagePanel;
        javax.swing.JPanel jPanel1;
        javax.swing.JPanel jPanel3;
        javax.swing.JLabel nameLabel;
        javax.swing.JPanel namePanel;
        javax.swing.JPanel spacer0;
        javax.swing.JPanel spacer1;

        componentPanel = new javax.swing.JPanel();
        componentPane = new ComponentDesignPane(inputs, outputs);
        spacer0 = new javax.swing.JPanel();
        namePanel = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        nameField = new javax.swing.JTextField();
        imagePanel = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        imageLabel = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        imageField = new javax.swing.JTextField();
        browseButton = new javax.swing.JButton();
        spacer1 = new javax.swing.JPanel();
        confirmPanel = new javax.swing.JPanel();
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();

        getContentPane().setLayout(new java.awt.GridBagLayout());

        setTitle("Create Custom Component");
        setModal(true);
        setResizable(false);
        componentPane.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.LOWERED));
        componentPane.setMinimumSize(new java.awt.Dimension(273, 173));
        componentPanel.add(componentPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        getContentPane().add(componentPanel, gridBagConstraints);

        spacer0.setMinimumSize(new java.awt.Dimension(10, 25));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        getContentPane().add(spacer0, gridBagConstraints);

        namePanel.setLayout(new java.awt.BorderLayout());

        jPanel3.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        nameLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        nameLabel.setText("Component Name:");
        jPanel3.add(nameLabel);

        namePanel.add(jPanel3, java.awt.BorderLayout.CENTER);

        nameField.setMinimumSize(new java.awt.Dimension(200, 20));
        nameField.setPreferredSize(new java.awt.Dimension(200, 20));
        nameField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                nameFieldKeyTyped(evt);
            }
        });

        jPanel1.add(nameField);

        namePanel.add(jPanel1, java.awt.BorderLayout.SOUTH);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        getContentPane().add(namePanel, gridBagConstraints);

        imagePanel.setLayout(new java.awt.BorderLayout());

        jPanel4.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        imageLabel.setText("Component Image:");
        jPanel4.add(imageLabel);

        imagePanel.add(jPanel4, java.awt.BorderLayout.CENTER);

        imageField.setEnabled(false);
        imageField.setMinimumSize(new java.awt.Dimension(200, 20));
        imageField.setPreferredSize(new java.awt.Dimension(200, 20));
        jPanel2.add(imageField);

        browseButton.setText("Browse...");
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                browseButtonClicked(evt);
            }
        });

        jPanel2.add(browseButton);

        imagePanel.add(jPanel2, java.awt.BorderLayout.SOUTH);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        getContentPane().add(imagePanel, gridBagConstraints);

        spacer1.setMinimumSize(new java.awt.Dimension(10, 20));
        spacer1.setPreferredSize(new java.awt.Dimension(10, 20));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        getContentPane().add(spacer1, gridBagConstraints);

        saveButton.setText("Save");
        saveButton.setEnabled(false);
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonClicked(evt);
            }
        });

        confirmPanel.add(saveButton);

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonClicked(evt);
            }
        });

        confirmPanel.add(cancelButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(confirmPanel, gridBagConstraints);

        pack();
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        java.awt.Dimension dialogSize = getSize();
        setLocation((screenSize.width-dialogSize.width)/2,(screenSize.height-dialogSize.height)/2);
    }//GEN-END:initComponents

    private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
        setVisible(false);
    }//GEN-LAST:event_cancelButtonClicked

    private void nameFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_nameFieldKeyTyped
        verifyForm();
    }//GEN-LAST:event_nameFieldKeyTyped

    private void saveButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonClicked
        optionChosen = OPTION_ACCEPT;
        setVisible(false);
    }//GEN-LAST:event_saveButtonClicked

    private void browseButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonClicked
        // set up the image file chooser
        JFileChooser chooser = new JFileChooser();
        chooser.setDialogTitle("Select Component Image...");
        chooser.setFileFilter(new ImageFileFilter());
        chooser.setAcceptAllFileFilterUsed(false);
        chooser.setMultiSelectionEnabled(false);
        
        if (chooser.showDialog(this, "Select Image") ==
                JFileChooser.APPROVE_OPTION) {
            // make sure the user selected a file that exists
            if (chooser.getSelectedFile().isFile() &&
                    chooser.getSelectedFile().exists()) {
                MediaTracker mediaTracker = new MediaTracker(this);
                Image userImage = Toolkit.getDefaultToolkit().getImage(
                        chooser.getSelectedFile().getAbsolutePath());
                mediaTracker.addImage(userImage, 0);
                
                try {
                    mediaTracker.waitForAll();
                    componentPane.setImage(userImage);
                    imageField.setText(
                            chooser.getSelectedFile().getAbsolutePath());
                }
                catch(InterruptedException e) {
                    componentPane.setImage(null);
                    imageField.setText("");
                }
            } else {
                componentPane.setImage(null);
                imageField.setText("");
            }
            
            verifyForm();
        }
    }//GEN-LAST:event_browseButtonClicked
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browseButton;
    private gui.ComponentDesignPane componentPane;
    private javax.swing.JTextField imageField;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JTextField nameField;
    private javax.swing.JButton saveButton;
    // End of variables declaration//GEN-END:variables
    
    /** the option chosen from this dialog, initialized to default */
    private int optionChosen = OPTION_CANCEL;
    /** the input components from the model that will become input pins */
    private HashSet inputs;
    /** the output components from the model that will become output pins */
    private HashSet outputs;

    /** the cancel option for this dialog, dont save the component */
    public static final int OPTION_CANCEL = 0;
    /** the accept option for this dialog, save the component */
    public static final int OPTION_ACCEPT = 1;
}
